package fr.umlv.authentication;

import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Image;
import java.awt.Insets;
import java.awt.LayoutManager;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigInteger;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.util.Locale;
import java.util.ResourceBundle;
import java.util.logging.Level;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;

import kiyut.ekspos.Application;
import kiyut.ekspos.BrowserWindow;

import org.apache.chemistry.opencmis.commons.exceptions.CmisConnectionException;
import org.apache.chemistry.opencmis.commons.exceptions.CmisRuntimeException;
import org.jdesktop.swingx.JXErrorPane;
import org.jdesktop.swingx.error.ErrorInfo;

import fr.umlv.main.SplashScreen;
import fr.umlv.model.ClientSession;

/**
 * The Class Connection.
 */
public class Connection extends JFrame {

	/** The Constant serialVersionUID. */
	private static final long serialVersionUID = 1L;

	/** The login. */
	private JTextField login;

	/** The password. */
	private JTextField password;

	/** The combobox lang. */
	private JComboBox comboboxLang;

	/** The lock. */
	private Object lock;

	/** The error. */
	final JLabel error = new JLabel();

	/** The client session. */
	private ClientSession clientSession;
	// bundle pour recuperer le texte de la fenetre d'authentification pour les
	// boutons...
	/** The bundle. */
	private ResourceBundle bundle = ResourceBundle.getBundle("kiyut.ekspos.BrowserWindow");

	/**
	 * Instantiates a new connection.
	 * 
	 * @param mylock
	 *            the mylock
	 */
	public Connection(Object mylock) {
		this.lock = mylock;
		init();
	}

	/**
	 * Inits the.
	 */
	private void init() {
		setUndecorated(true);
		JLayeredPane pane = new JLayeredPane();
		setTitle(bundle.getString("TitleAuth.text"));
		setIconImage(Toolkit.getDefaultToolkit().createImage(Application.class.getResource("/kiyut/ekspos/sabre.png")));
		ImageIcon image = new ImageIcon(Toolkit.getDefaultToolkit().createImage(Application.class.getResource("/kiyut/ekspos/loginbg.png")));
		final JLabel background = new JLabel(image);
		background.setOpaque(true);
		pane.add(background, Integer.valueOf(0));

		GridBagLayout g = new GridBagLayout();
		JPanel pan_principal = new JPanel(g);
		pan_principal.setOpaque(false);
		GridBagConstraints gbc = new GridBagConstraints();

		final Connection c = this;

		// ajouter une image en fond d'écran et non de la couleur
		// pan_principal.setBackground(new Color(225,254,250));

		ImageIcon imagePres = new ImageIcon(Toolkit.getDefaultToolkit().createImage(Application.class.getResource("/kiyut/ekspos/logoUPE.gif")));
		Image im = imagePres.getImage();
		// im = im.getScaledInstance(300,80,Image.SCALE_DEFAULT);

		final JLabel bg = new JLabel(new ImageIcon(im));
		bg.setOpaque(false);
		gbc.anchor = GridBagConstraints.WEST;
		gbc.gridwidth = GridBagConstraints.REMAINDER;
		Insets insets = new Insets(10, 10, 0, 10);
		gbc.weightx = 1f;
		// gbc.weighty=1f;
		gbc.insets = insets;
		pan_principal.add(bg, gbc);
		comboboxLang = new JComboBox();

		// ajout des langues dans la combo box
		comboboxLang.addItem(bundle.getString("Fr.text"));
		comboboxLang.addItem(bundle.getString("En.text"));

		final JLabel labelLogin = new JLabel(bundle.getString("Login.text"));
		labelLogin.setForeground(new Color(128, 128, 128));
		labelLogin.setFont(new Font("Arial", Font.BOLD, 12));
		final JLabel labelPwd = new JLabel(bundle.getString("Pwd.text"));
		labelPwd.setForeground(new Color(128, 128, 128));
		labelPwd.setFont(new Font("Arial", Font.BOLD, 12));
		final JLabel labelLang = new JLabel(bundle.getString("Lang.text"));
		labelLang.setFont(new Font("Arial", Font.BOLD, 12));
		labelLang.setForeground(new Color(128, 128, 128));
		gbc = new GridBagConstraints();
		insets = new Insets(40, 40, 2, 10);
		gbc.anchor = GridBagConstraints.WEST;
		gbc.gridwidth = GridBagConstraints.REMAINDER;
		gbc.insets = insets;
		pan_principal.add(labelLogin, gbc);
		gbc.gridwidth = GridBagConstraints.REMAINDER;
		login = new JTextField(25);
		insets = new Insets(2, 40, 2, 10);
		gbc.insets = insets;
		pan_principal.add(login, gbc);
		gbc.gridwidth = GridBagConstraints.REMAINDER;
		pan_principal.add(labelPwd, gbc);
		password = new JPasswordField(25);
		gbc.gridwidth = GridBagConstraints.REMAINDER;
		pan_principal.add(password, gbc);
		gbc.gridwidth = GridBagConstraints.REMAINDER;
		insets = new Insets(2, 40, 2, 0);
		gbc.insets = insets;
		JPanel panLang = new JPanel();
		panLang.add(labelLang);
		panLang.add(comboboxLang);
		panLang.setOpaque(false);
		pan_principal.add(panLang, gbc);
		gbc.gridwidth = GridBagConstraints.REMAINDER;
		insets = new Insets(2, 0, 2, 0);
		gbc.insets = insets;
		// gbc.anchor=GridBagConstraints.WEST;
		// pan_principal.add(comboboxLang,gbc);

		// creation du panel contenant les boutons valider et annuler
		final JButton ok = new JButton(bundle.getString("SubmitLogin.text"));
		ok.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				try {
					doAction();
				} catch (KeyManagementException e1) {
					ErrorInfo info = new ErrorInfo(e1.getMessage(), "KeyManagementException", null, "KeyManagementException", e1, Level.SEVERE, null);
					JXErrorPane.showDialog(c, info);
				} catch (KeyStoreException e1) {
					ErrorInfo info = new ErrorInfo(e1.getMessage(), "KeyStoreException", null, "KeyStoreException", e1, Level.SEVERE, null);
					JXErrorPane.showDialog(c, info);
				} catch (NoSuchAlgorithmException e1) {
					ErrorInfo info = new ErrorInfo(e1.getMessage(), "NoSuchAlgorithmException", null, "NoSuchAlgorithmException", e1, Level.SEVERE, null);
					JXErrorPane.showDialog(c, info);
				} catch (CertificateException e1) {
					ErrorInfo info = new ErrorInfo(e1.getMessage(), "CertificateException", null, "CertificateException", e1, Level.SEVERE, null);
					JXErrorPane.showDialog(c, info);
				} catch (IOException e1) {
					ErrorInfo info = new ErrorInfo(e1.getMessage(), "IOException", null, "IOException", e1, Level.SEVERE, null);
					JXErrorPane.showDialog(c, info);
				}
			}
		});
		getRootPane().setDefaultButton(ok);
		final JButton annuler = new JButton(bundle.getString("Cancel.text"));
		annuler.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				System.exit(0);
			}
		});
		final Connection connection = this;
		comboboxLang.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				if (comboboxLang.getSelectedIndex() == 0) {
					bundle = ResourceBundle.getBundle("kiyut.ekspos.BrowserWindow");
					labelLogin.setText(bundle.getString("Login.text"));
					labelPwd.setText(bundle.getString("Pwd.text"));
					labelLang.setText(bundle.getString("Lang.text"));
					annuler.setText(bundle.getString("Cancel.text"));
					ok.setText(bundle.getString("SubmitLogin.text"));
					error.setText("");
					connection.validate();
					connection.repaint();
				} else if (comboboxLang.getSelectedIndex() == 1) {
					bundle = ResourceBundle.getBundle("kiyut.ekspos.BrowserWindow", Locale.ENGLISH);
					labelLogin.setText(bundle.getString("Login.text"));
					labelPwd.setText(bundle.getString("Pwd.text"));
					labelLang.setText(bundle.getString("Lang.text"));
					annuler.setText(bundle.getString("Cancel.text"));
					ok.setText(bundle.getString("SubmitLogin.text"));
					error.setText("");
					connection.validate();
					connection.repaint();
				}
			}
		});

		JPanel panButton = new JPanel();
		panButton.add(ok);
		panButton.add(annuler);
		panButton.setOpaque(false);
		gbc = new GridBagConstraints();
		gbc.gridwidth = GridBagConstraints.REMAINDER;
		// gbc.anchor=GridBagConstraints.WEST;
		// insets = new Insets(2,40 , 2, 10);
		// gbc.insets=insets;
		pan_principal.add(panButton, gbc);
		// pan_principal.add(annuler,gbc);
		error.setForeground(Color.red);
		error.setFont(new Font("Arial", Font.BOLD, 12));
		pan_principal.add(error, gbc);

		// addWindowListener(new WindowAdapter() {
		// public void windowClosing(WindowEvent e) {
		// System.exit(0);
		// };
		// });
		pane.add(pan_principal, Integer.valueOf(1));
		pane.setLayout(new LayoutManager() {
			public void addLayoutComponent(String name, Component comp) {
			}

			public void removeLayoutComponent(Component comp) {
			}

			public Dimension preferredLayoutSize(Container parent) {
				Component[] components = parent.getComponents();
				if (components.length == 0) {
					return new Dimension(0, 0);
				}
				Dimension d = components[0].getPreferredSize();
				for (int i = 1; i < components.length; i++) {
					Dimension tmp = components[i].getPreferredSize();
					if (d.width < tmp.width)
						d.width = tmp.width;
					if (d.height < tmp.height)
						d.height = tmp.height;
				}
				return d;
			}

			public Dimension minimumLayoutSize(Container parent) {
				Component[] components = parent.getComponents();
				if (components.length == 0) {
					return new Dimension(0, 0);
				}
				Dimension d = components[0].getMinimumSize();
				for (int i = 1; i < components.length; i++) {
					Dimension tmp = components[i].getMinimumSize();
					if (d.width < tmp.width)
						d.width = tmp.width;
					if (d.height < tmp.height)
						d.height = tmp.height;
				}
				return d;
			}

			public void layoutContainer(Container parent) {
				Dimension d = parent.getSize();
				for (Component c : parent.getComponents()) {
					c.setSize(d);
				}
			}
		});

		getContentPane().add(pane);
		BrowserWindow.loadBlacklist();
	}

	/**
	 * Do action.
	 * 
	 * @throws KeyManagementException
	 *             the key management exception
	 * @throws KeyStoreException
	 *             the key store exception
	 * @throws NoSuchAlgorithmException
	 *             the no such algorithm exception
	 * @throws CertificateException
	 *             the certificate exception
	 * @throws IOException
	 *             Signals that an I/O exception has occurred.
	 */
	public void doAction() throws KeyManagementException, KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException {
		String strLogin = login.getText();
		String strPwd = password.getText();
		if (strLogin.equals("")) {
			error.setText(bundle.getString("ErrorLogin.text"));
			return;
		}

		try {
			if (clientSession == null) {

				SessionHandler.setClientSession(strLogin, strPwd, comboboxLang.getSelectedItem().toString(), this);
				SessionHandler.setLogin(strLogin);

				createShortcut();

				SplashScreen.getInstance().showSplashScreen();
				this.dispose();

				synchronized (lock) {
					lock.notify();
				}
			}
		} catch (CmisConnectionException e) {
			// erreur de connexion CMIS
			error.setText(bundle.getString("ErrorConnection.text"));
		} catch (CmisRuntimeException e) {

			if (e.getMessage().equals("Unauthorized") || e.getCode().equals(BigInteger.ZERO)) {
				error.setText(bundle.getString("ErrorLogin.text"));
				login.setText("");
				password.setText("");
			} else {
				error.setText(bundle.getString("ErrorIntern.text"));
			}
		}
	}

	private void createShortcut() {

		//TODO : checker dans Preferences utilisateurs
		if (true) { 

			if (System.getProperty("os.name").toUpperCase().startsWith("WINDOWS")) {

				File desktopPath = new File(System.getProperty("user.home") + File.separator + "Desktop");
				if (!desktopPath.exists()) {
					desktopPath = new File(System.getProperty("user.home") + File.separator + "Bureau");
				}

				if (!desktopPath.exists())
					return;
				
				InputStream in;
				File out;
				try {
					in = getClass().getResource("/shortcut/GED-I.lnk").openStream();
					out = new File(desktopPath + File.separator + "GED-I.lnk");
					copyStreamToFile(in, out);
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

	public void copyStreamToFile(InputStream in, File fOut) {

		try {

			OutputStream out = new FileOutputStream(fOut);

			byte[] buf = new byte[10];
			int len;
			while ((len = in.read(buf)) > 0) {
				out.write(buf, 0, len);
			}
			in.close();
			out.close();

		} catch (IOException e) {
			e.printStackTrace();
		}

	}

}
